package com.ujn.demo.use;

import com.alibaba.fastjson.JSON;
import com.ujn.demo.model.ClockTime;
import com.ujn.demo.model.StaffModel;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

import static com.ujn.demo.common.CommonUtils.*;

/**
 * 计算生产部工人工时
 * 规则：
 * 工作日：
 * 打卡情况
 *      1 2 3 4 5 6
 *      √ √ √ √ × ×
 *      √ √ √ √ √ √
 *      √ √ √ _ √ ×
 *      √ √ √ √ × ×
 * 周末：
 */
public class CalculateWorkerWorkTime {

    private static final Logger LOGGER = LoggerFactory.getLogger(CalculateWorkerWorkTime.class);

    /**
     * excel地址
     */
    private static final String folderPath = "C:\\Users\\可爱的小宝贝\\Desktop\\身份证\\0405";

    private static final String filePath = folderPath + "\\生产部_全部.xls";

    private static Map<Integer, StaffModel> map = new HashMap<>(8000);

    public static void main(String[] args) throws Exception {
        //读取excel
        readExcel();
        //写入excel
        writeExcel();
    }

    /**
     * 写excel
     * @throws IOException
     */
    public static void writeExcel() throws IOException {
        try{
            // 创建工作薄
            HSSFWorkbook workbook = new HSSFWorkbook();
            // 创建工作表
            HSSFSheet sheet = workbook.createSheet("sheet1");

            //设置标头
            HSSFRow zeroRows = sheet.createRow(0);
            zeroRows.createCell(0).setCellValue("考勤号码");
            zeroRows.createCell(1).setCellValue("姓名");
            zeroRows.createCell(2).setCellValue("部门");
            zeroRows.createCell(3).setCellValue("日期");
            zeroRows.createCell(4).setCellValue("时间");
            zeroRows.createCell(5).setCellValue("打卡1");
            zeroRows.createCell(6).setCellValue("打卡2");
            zeroRows.createCell(7).setCellValue("打卡3");
            zeroRows.createCell(8).setCellValue("打卡4");
            zeroRows.createCell(9).setCellValue("打卡5");
            zeroRows.createCell(10).setCellValue("打卡6");
            zeroRows.createCell(11).setCellValue("异常:1 异常标记；2 迟到标记");
            zeroRows.createCell(12).setCellValue("正班工时");
            zeroRows.createCell(13).setCellValue("加班工时");
            zeroRows.createCell(14).setCellValue("夜宵补贴");
            zeroRows.createCell(15).setCellValue("迟到时间");

            //row 行数
            for (int row = 1; row <= map.size(); row++) {
                HSSFRow rows = sheet.createRow(row);
                //获取staffModel, clo列数
                StaffModel staffModel = map.get(row);
                ClockTime clockTime = staffModel.getClockTime();
                for (int col = 0; col < 16; col++) {
                    if (col == 0){
                        rows.createCell(col).setCellValue(staffModel.getNumber());
                    }else if (col == 1){
                        rows.createCell(col).setCellValue(staffModel.getName());
                    }else if (col == 2){
                        rows.createCell(col).setCellValue(staffModel.getDepartment());
                    }else if (col == 3){
                        rows.createCell(col).setCellValue(staffModel.getDateTime());
                    }else if (col == 4){
                        rows.createCell(col).setCellValue(staffModel.getTime());
                    }else if (col == 5 && Objects.nonNull(clockTime)){
                        String time = StringUtils.isEmpty(clockTime.getFirstTime())?"":clockTime.getFirstTime();
                        rows.createCell(col).setCellValue(time);
                    }else if (col == 6 && Objects.nonNull(clockTime)){
                        String time = StringUtils.isEmpty(clockTime.getSecondTime())?"":clockTime.getSecondTime();
                        rows.createCell(col).setCellValue(time);
                    }else if (col == 7 && Objects.nonNull(clockTime)){
                        String time = StringUtils.isEmpty(clockTime.getThirdTime())?"":clockTime.getThirdTime();
                        rows.createCell(col).setCellValue(time);
                    }else if (col == 8 && Objects.nonNull(clockTime)){
                        String time = StringUtils.isEmpty(clockTime.getFourthTime())?"":clockTime.getFourthTime();
                        rows.createCell(col).setCellValue(time);
                    }else if (col == 9 && Objects.nonNull(clockTime)){
                        String time = StringUtils.isEmpty(clockTime.getFifthTime())?"":clockTime.getFifthTime();
                        rows.createCell(col).setCellValue(time);
                    }else if (col == 10 && Objects.nonNull(clockTime)){
                        String time = StringUtils.isEmpty(clockTime.getSixthTime())?"":clockTime.getSixthTime();
                        rows.createCell(col).setCellValue(time);
                    }else if (col == 11 && Objects.nonNull(staffModel.getIsException()) && !staffModel.getIsException().equals("0")){
                        rows.createCell(col).setCellValue(staffModel.getIsException());
                    }else if (col == 12 && Objects.nonNull(staffModel.getNormalHours())){
                        rows.createCell(col).setCellValue(staffModel.getNormalHours());
                    }else if (col == 13 && Objects.nonNull(staffModel.getExtraHours()) && staffModel.getNormalHours()!=0f){
                        rows.createCell(col).setCellValue(staffModel.getExtraHours());
                    }else if (col == 14 && Objects.nonNull(staffModel.getIsSubsidy()) && staffModel.getIsSubsidy()!=0){
                        rows.createCell(col).setCellValue(staffModel.getIsSubsidy());
                    }else if (col == 15 && Objects.nonNull(staffModel.getLateMinutes()) && staffModel.getLateMinutes()!=0){
                        rows.createCell(col).setCellValue(staffModel.getLateMinutes());
                    }
                }
            }
            String []str = filePath.split("\\.");
            String createFile = str[0] + "-" + getTime() + "." + str[1];
            File xlsFile = new File(createFile);
            xlsFile.createNewFile();
            FileOutputStream xlsStream = new FileOutputStream(xlsFile);
            workbook.write(xlsStream);
            LOGGER.info("writeExcel，计算生产部工时成功，请查看excel位置：{}", xlsFile.getAbsolutePath());
        }catch (Exception e){
            LOGGER.error("writeExcel，错误：{}", e.getMessage());
        }
    }

    /**
     * 读取excel
     * @throws IOException
     * @throws InvalidFormatException
     */
    public static void readExcel() throws Exception {
        File xlsFile = new File(filePath);
        // 获得工作簿
        Workbook workbook = WorkbookFactory.create(xlsFile);
        // 获得工作表个数
        int sheetCount = workbook.getNumberOfSheets();
        int normalCount = 0;
        // 遍历工作表
        for (int i = 0; i < sheetCount; i++) {
            Sheet sheet = workbook.getSheetAt(i);
            // 获得行数
            int rows = sheet.getLastRowNum() + 1;
            // 获得列数，先获得一行，再得到该行列数
            Row tmp = sheet.getRow(0);
            if (tmp == null) {
                continue;
            }
            //读取数据
            for (int row = 1; row < rows; row++) {//获取第几行
                Row r = sheet.getRow(row);
                StaffModel staffModel = new StaffModel();
                for (int col = 0; col < 5; col++) {//获取列数
                    try {
                        String str = r.getCell(col).getStringCellValue();
                        if (col == 0){
                            staffModel.setNumber(str);
                        }else if (col == 1){
                            staffModel.setName(str);
                        }else if (col == 2){
                            staffModel.setDepartment(str);
                        }else if (col == 3){
                            staffModel.setDateTime(str);
                        }else if (col == 4){
                            staffModel.setTime(str);
                        }
                        map.put(row, staffModel);
                    }catch (Exception e){
                        LOGGER.error("出错：{}, 编号：{}, staffModel:{}", e.getMessage(), row, JSON.toJSON(staffModel));
                    }
                }
                LOGGER.info("输出row:{},staffModel:{}", row, JSON.toJSON(staffModel));
                //整理好staffModel的值
                normalCount = getNormalCount(normalCount, staffModel);
            }
            LOGGER.info("正常条数：{}，输出map:{}", normalCount, JSON.toJSON(map));
        }
    }

    /**
     * 整理好staffModel的值
     * @param normalCount
     * @param staffModel
     * @return
     * @throws Exception
     */
    private static int getNormalCount(int normalCount, StaffModel staffModel) throws Exception {
        String dateTime = staffModel.getDateTime();
        int dayForWeek = dayForWeek(dateTime);
        //正常为0
        String isException = "0";
        //标注日期周末，判断是否周末，或者工作日，两者使用规则不一样
        if (dayForWeek>=1 && dayForWeek <=5){
            //工作日时间，转化时间
            if (StringUtils.isEmpty(staffModel.getTime())){
                //异常为1
                staffModel.setIsException("1-打卡异常");
            }else{
                ClockTime clockTime = sortClockTime(staffModel.getTime(), false);
                staffModel.setClockTime(clockTime);
                //前三个卡必须打上的
                if (Objects.isNull(clockTime) || StringUtils.isEmpty(clockTime.getFirstTime()) || StringUtils.isEmpty(clockTime.getSecondTime()) || StringUtils.isEmpty(clockTime.getThirdTime())){
                    //异常为1
                    staffModel.setIsException("1-打卡异常");
                }else if(!StringUtils.isEmpty(clockTime.getFirstTime()) && (getHourOrMinute(clockTime.getFirstTime(), true) >= 0 && getHourOrMinute(clockTime.getFirstTime(), true) <= 6 )){
                    //凌晨卡的出现
                    staffModel.setIsException("1-上夜班，注意前一天记录");
                }else if(!StringUtils.isEmpty(clockTime.getFourthTime()) && StringUtils.isEmpty(clockTime.getFifthTime()) && StringUtils.isEmpty(clockTime.getSixthTime())){
                    //打前四个卡,五六卡空，,连着的两个打卡时间不能少于15分钟
                    if (callTime(clockTime.getThirdTime(), clockTime.getSecondTime())<=15){
                        staffModel.setIsException("1-连卡少于15分钟");
                    }else{
                        normalCount++;
                        //迟到几分钟
                        int lateMinutes = calculateLateMinutes(clockTime);
                        float hours = 0f;
                        if (lateMinutes > 0){
                            staffModel.setLateMinutes(lateMinutes);
                            isException = "2-迟到";
                            if (lateMinutes > 30){
                                hours = (float) Math.ceil(new BigDecimal(String.valueOf(lateMinutes/30f)).doubleValue())*0.5f;
                            }
                        }
                        //计算正常工时
                        staffModel.setNormalHours(8f - hours);
                        staffModel.setIsException(isException);
                    }
                }else if(!StringUtils.isEmpty(clockTime.getFourthTime()) && !StringUtils.isEmpty(clockTime.getFifthTime()) && !StringUtils.isEmpty(clockTime.getSixthTime())){
                    //打前六个卡,连着的两个打卡时间不能少于15分钟
                    if (callTime(clockTime.getThirdTime(), clockTime.getSecondTime())<=15 || callTime(clockTime.getFifthTime(), clockTime.getFourthTime())<=15){
                        staffModel.setIsException("1-连卡少于15分钟");
                    }else{
                        normalCount++;
                        //迟到几分钟
                        int lateMinutes = calculateLateMinutes(clockTime);
                        float hours = 0f;
                        if (lateMinutes > 0){
                            staffModel.setLateMinutes(lateMinutes);
                            isException = "2-迟到";
                            if (lateMinutes > 30){
                                hours = (float) Math.ceil(new BigDecimal(String.valueOf(lateMinutes/30f)).doubleValue())*0.5f;
                            }
                        }
                        //计算正常工时
                        staffModel.setNormalHours(8f - hours);
                        if (!StringUtils.isEmpty(clockTime.getSixthTime())){
                            //计算加班工时
                            staffModel.setExtraHours(calculateExtraHours(clockTime.getSixthTime(), "18:30"));
                            //是否有宵夜（23:00分之后）
                            staffModel.setIsSubsidy(calculateIsSubsidy(clockTime));
                        }
                        staffModel.setIsException(isException);
                    }
                }else if(StringUtils.isEmpty(clockTime.getFourthTime()) && !StringUtils.isEmpty(clockTime.getFifthTime()) && StringUtils.isEmpty(clockTime.getSixthTime())){
                    //打一、二、三、五个卡（这是连班，第四、六个卡可不打，第五个卡的时间必须是<21:00，否则报错）
                    if (callTime(clockTime.getThirdTime(), clockTime.getSecondTime())<=15 || callTime(clockTime.getFifthTime(), "21:00") > 0){//返回异常
                        staffModel.setIsException("1-连卡少于15分钟或下班超21点");
                    }else{
                        normalCount++;
                        //迟到几分钟
                        int lateMinutes = calculateLateMinutes(clockTime);
                        float hours = 0f;
                        if (lateMinutes > 0){
                            staffModel.setLateMinutes(lateMinutes);
                            isException = "2-迟到";
                            if (lateMinutes > 30){
                                hours = (float) Math.ceil(new BigDecimal(String.valueOf(lateMinutes/30f)).doubleValue())*0.5f;
                            }
                        }
                        //计算正常工时
                        staffModel.setNormalHours(8f - hours);
                        if (!StringUtils.isEmpty(clockTime.getFifthTime())){
                            //计算加班工时,连卡加班从17:30算起
                            staffModel.setExtraHours(calculateExtraHours(clockTime.getFifthTime(), "17:30"));
                            //是否有宵夜（23:00分之后）
                            staffModel.setIsSubsidy(calculateIsSubsidy(clockTime));
                        }
                        staffModel.setIsException(isException);
                    }
                }else if(StringUtils.isEmpty(clockTime.getFourthTime()) && StringUtils.isEmpty(clockTime.getFifthTime()) && !StringUtils.isEmpty(clockTime.getSixthTime())){
                    //打一、二、三、六个卡（这是连班，第四、五个卡可不打，第六个卡的时间必须是<21:00，否则报错）
                    if (callTime(clockTime.getThirdTime(), clockTime.getSecondTime())<=15 || callTime(clockTime.getSixthTime(), "21:00") > 0){//返回异常
                        staffModel.setIsException("1-连卡少于15分钟或下班超21点");
                    }else{
                        normalCount++;
                        //迟到几分钟
                        int lateMinutes = calculateLateMinutes(clockTime);
                        float hours = 0f;
                        if (lateMinutes > 0){
                            staffModel.setLateMinutes(lateMinutes);
                            isException = "2-迟到";
                            if (lateMinutes > 30){
                                hours = (float) Math.ceil(new BigDecimal(String.valueOf(lateMinutes/30f)).doubleValue())*0.5f;
                            }
                        }
                        //计算正常工时
                        staffModel.setNormalHours(8f - hours);
                        if (!StringUtils.isEmpty(clockTime.getSixthTime())){
                            //计算加班工时,连卡加班从17:30算起
                            staffModel.setExtraHours(calculateExtraHours(clockTime.getSixthTime(), "17:30"));
                            //是否有宵夜（23:00分之后）
                            staffModel.setIsSubsidy(calculateIsSubsidy(clockTime));
                        }
                        staffModel.setIsException(isException);
                    }
                }else{
                    staffModel.setIsException("1-打卡异常");
                }
            }
        }else{
            //设置周末时间
            String str = dateTime + "-星期六";
            if(dayForWeek == 7){
                str = dateTime + "-星期日";
            }
            staffModel.setDateTime(str);
            //周末时间，转化时间
            if (StringUtils.isEmpty(staffModel.getTime())){
                //异常为1
                //staffModel.setIsException("1-打卡异常");
            }else{
                ClockTime clockTime = sortClockTime(staffModel.getTime(), true);
                staffModel.setClockTime(clockTime);
                if (Objects.isNull(clockTime) || clockTimeEmpty(clockTime)){//全部为空
                }else if(StringUtils.isNotEmpty(clockTime.getFirstTime()) && (getHourOrMinute(clockTime.getFirstTime(), true) >= 0 && getHourOrMinute(clockTime.getFirstTime(), true) <= 6 )) {
                    //凌晨卡的出现
                    staffModel.setIsException("1-上夜班，注意前一天记录");
                }else if (only12IsNotEmpty(clockTime) || only1234IsNotEmpty(clockTime)  || only123456IsNotEmpty(clockTime)){//判断clockTime仅打卡1、2不为空 或者 仅打卡1、2、3、4不为空 或者 仅打卡1、2、3、4、5、6不为空
                    if((only1234IsNotEmpty(clockTime) || only123456IsNotEmpty(clockTime)) && callTime(clockTime.getThirdTime(), clockTime.getSecondTime())<=15){
                        isException = "1-连卡少于15分钟";
                    }
                    normalCount++;
                    //迟到几分钟
                    int lateMinutes = calculateLateMinutes(clockTime);
                    float hours = 0f;
                    if (lateMinutes > 0){
                        staffModel.setLateMinutes(lateMinutes);
                        isException = "2-迟到";
                        if (lateMinutes > 30){
                            hours = (float) Math.ceil(new BigDecimal(String.valueOf(lateMinutes/30f)).doubleValue())*0.5f;
                        }
                    }
                    //计算正常工时
                    float normalHours = 8f;
                    if (only12IsNotEmpty(clockTime)){
                        normalHours = 3.5f;
                    }
                    if (only123456IsNotEmpty(clockTime) && StringUtils.isNotEmpty(clockTime.getSixthTime())){
                        //计算加班工时,加班从18:30算起
                        staffModel.setExtraHours(calculateExtraHours(clockTime.getSixthTime(), "18:30"));
                        //是否有宵夜（23:00分之后）
                        staffModel.setIsSubsidy(calculateIsSubsidy(clockTime));
                    }
                    staffModel.setNormalHours(normalHours - hours);
                    staffModel.setIsException(isException);
                }else if (only1235IsNotEmpty(clockTime) || only1236IsNotEmpty(clockTime)){//判断clockTime仅打卡1235不为空 或者 仅打卡1236不为空
                    if(callTime(clockTime.getThirdTime(), clockTime.getSecondTime())<=15
                            || (StringUtils.isNotEmpty(clockTime.getFifthTime()) && callTime(clockTime.getFifthTime(), "21:00") > 0)
                            || (StringUtils.isNotEmpty(clockTime.getSixthTime()) && callTime(clockTime.getSixthTime(), "21:00") > 0)){
                        isException = "1-连卡少于15分钟或者下班超过21:30";
                    }
                    //迟到几分钟
                    int lateMinutes = calculateLateMinutes(clockTime);
                    float hours = 0f;
                    if (lateMinutes > 0){
                        staffModel.setLateMinutes(lateMinutes);
                        isException = "2-迟到";
                        if (lateMinutes > 30){
                            hours = (float) Math.ceil(new BigDecimal(String.valueOf(lateMinutes/30f)).doubleValue())*0.5f;
                        }
                    }
                    //计算正常工时
                    staffModel.setNormalHours(8f - hours);
                    String endTime = only1235IsNotEmpty(clockTime)?clockTime.getFifthTime():clockTime.getSixthTime();
                    staffModel.setExtraHours(calculateExtraHours(endTime, "17:30"));
                    staffModel.setIsSubsidy(calculateIsSubsidy(clockTime));
                    staffModel.setIsException(isException);
                }else if (only34IsNotEmpty(clockTime) || only35IsNotEmpty(clockTime) || only36IsNotEmpty(clockTime) || only3456IsNotEmpty(clockTime)){
                    //
                    if( only3456IsNotEmpty(clockTime) && callTime(clockTime.getFifthTime(), clockTime.getFourthTime())<=15
                            || (only35IsNotEmpty(clockTime) && callTime(clockTime.getFifthTime(), "21:00") > 0)
                            || (only36IsNotEmpty(clockTime) && callTime(clockTime.getSixthTime(), "21:00") > 0)){
                        isException = "1-连卡少于15分钟或者下班超过21:30";
                    }
                    //迟到几分钟
                    int lateMinutes = calculateLateMinutes(clockTime);
                    float hours = 0f;
                    if (lateMinutes > 0){
                        staffModel.setLateMinutes(lateMinutes);
                        isException = "2-迟到";
                        if (lateMinutes > 30){
                            hours = (float) Math.ceil(new BigDecimal(String.valueOf(lateMinutes/30f)).doubleValue())*0.5f;
                        }
                    }
                    //计算正常工时
                    staffModel.setNormalHours(4.5f - hours);
                    //加班
                    if (!only34IsNotEmpty(clockTime)){
                        String startTime = only3456IsNotEmpty(clockTime)?"18:30":"17:30";
                        String endTime = only35IsNotEmpty(clockTime)?clockTime.getFifthTime():clockTime.getSixthTime();
                        //计算加班工时,加班从18:30算起
                        staffModel.setExtraHours(calculateExtraHours(endTime, startTime));
                    }
                    staffModel.setIsSubsidy(calculateIsSubsidy(clockTime));
                    staffModel.setIsException(isException);
                }else{
                    staffModel.setIsException("1-打卡异常");
                }
            }
        }
        return normalCount;
    }

    /**
     * 判断clockTime仅打卡3、4、5、6不为空
     * @param clockTime
     * @return
     */
    private static boolean only3456IsNotEmpty(ClockTime clockTime){
        boolean flag = StringUtils.isEmpty(clockTime.getFirstTime()) && StringUtils.isEmpty(clockTime.getSecondTime()) && StringUtils.isNotEmpty(clockTime.getThirdTime())
                && StringUtils.isNotEmpty(clockTime.getFourthTime()) && StringUtils.isNotEmpty(clockTime.getFifthTime()) && StringUtils.isNotEmpty(clockTime.getSixthTime());
        return flag;
    }

    /**
     * 判断clockTime仅打卡1、2、3、6不为空
     * @param clockTime
     * @return
     */
    private static boolean only1236IsNotEmpty(ClockTime clockTime){
        boolean flag = StringUtils.isNotEmpty(clockTime.getFirstTime()) && StringUtils.isNotEmpty(clockTime.getSecondTime()) && StringUtils.isNotEmpty(clockTime.getThirdTime())
                && StringUtils.isEmpty(clockTime.getFourthTime()) && StringUtils.isEmpty(clockTime.getFifthTime()) && StringUtils.isNotEmpty(clockTime.getSixthTime());
        return flag;
    }

    /**
     * 判断clockTime仅打卡1、2、3、5不为空
     * @param clockTime
     * @return
     */
    private static boolean only1235IsNotEmpty(ClockTime clockTime){
        boolean flag = StringUtils.isNotEmpty(clockTime.getFirstTime()) && StringUtils.isNotEmpty(clockTime.getSecondTime()) && StringUtils.isNotEmpty(clockTime.getThirdTime())
                && StringUtils.isEmpty(clockTime.getFourthTime()) && StringUtils.isNotEmpty(clockTime.getFifthTime()) && StringUtils.isEmpty(clockTime.getSixthTime());
        return flag;
    }

    /**
     * 判断clockTime仅打卡3、6不为空
     * @param clockTime
     * @return
     */
    private static boolean only36IsNotEmpty(ClockTime clockTime){
        boolean flag = StringUtils.isEmpty(clockTime.getFirstTime()) && StringUtils.isEmpty(clockTime.getSecondTime()) && StringUtils.isNotEmpty(clockTime.getThirdTime())
                && StringUtils.isEmpty(clockTime.getFourthTime()) && StringUtils.isEmpty(clockTime.getFifthTime()) && StringUtils.isNotEmpty(clockTime.getSixthTime());
        return flag;
    }

    /**
     * 判断clockTime仅打卡3、5不为空
     * @param clockTime
     * @return
     */
    private static boolean only35IsNotEmpty(ClockTime clockTime){
        boolean flag = StringUtils.isEmpty(clockTime.getFirstTime()) && StringUtils.isEmpty(clockTime.getSecondTime()) && StringUtils.isNotEmpty(clockTime.getThirdTime())
                && StringUtils.isEmpty(clockTime.getFourthTime()) && StringUtils.isNotEmpty(clockTime.getFifthTime()) && StringUtils.isEmpty(clockTime.getSixthTime());
        return flag;
    }

    /**
     * 判断clockTime仅打卡3、4不为空
     * @param clockTime
     * @return
     */
    private static boolean only34IsNotEmpty(ClockTime clockTime){
        boolean flag = StringUtils.isEmpty(clockTime.getFirstTime()) && StringUtils.isEmpty(clockTime.getSecondTime()) && StringUtils.isNotEmpty(clockTime.getThirdTime())
                && StringUtils.isNotEmpty(clockTime.getFourthTime()) && StringUtils.isEmpty(clockTime.getFifthTime()) && StringUtils.isEmpty(clockTime.getSixthTime());
        return flag;
    }

    /**
     * 判断clockTime仅打卡1、2、3、4、5、6不为空
     * @param clockTime
     * @return
     */
    private static boolean only123456IsNotEmpty(ClockTime clockTime){
        boolean flag = StringUtils.isNotEmpty(clockTime.getFirstTime()) && StringUtils.isNotEmpty(clockTime.getSecondTime()) && StringUtils.isNotEmpty(clockTime.getThirdTime())
                && StringUtils.isNotEmpty(clockTime.getFourthTime()) && StringUtils.isNotEmpty(clockTime.getFifthTime()) && StringUtils.isNotEmpty(clockTime.getSixthTime());
        return flag;
    }

    /**
     * 判断clockTime仅打卡1、2、3、4不为空
     * @param clockTime
     * @return
     */
    private static boolean only1234IsNotEmpty(ClockTime clockTime){
        boolean flag = StringUtils.isNotEmpty(clockTime.getFirstTime()) && StringUtils.isNotEmpty(clockTime.getSecondTime()) && StringUtils.isNotEmpty(clockTime.getThirdTime())
                && StringUtils.isNotEmpty(clockTime.getFourthTime()) && StringUtils.isEmpty(clockTime.getFifthTime()) && StringUtils.isEmpty(clockTime.getSixthTime());
        return flag;
    }

    /**
     * 判断clockTime仅打卡1、2不为空
     * @param clockTime
     * @return
     */
    private static boolean only12IsNotEmpty(ClockTime clockTime){
        boolean flag = StringUtils.isNotEmpty(clockTime.getFirstTime()) && StringUtils.isNotEmpty(clockTime.getSecondTime()) && StringUtils.isEmpty(clockTime.getThirdTime())
                && StringUtils.isEmpty(clockTime.getFourthTime()) && StringUtils.isEmpty(clockTime.getFifthTime()) && StringUtils.isEmpty(clockTime.getSixthTime());
        return flag;
    }

    /**
     * 判断clockTime是否全部为空
     * @param clockTime
     * @return
     */
    private static boolean clockTimeEmpty(ClockTime clockTime){
        boolean flag = StringUtils.isEmpty(clockTime.getFirstTime()) && StringUtils.isEmpty(clockTime.getSecondTime()) && StringUtils.isEmpty(clockTime.getThirdTime())
                && StringUtils.isEmpty(clockTime.getFourthTime()) && StringUtils.isEmpty(clockTime.getFifthTime()) && StringUtils.isEmpty(clockTime.getSixthTime());
        return flag;
    }

    /**
     * 计算是否有宵夜（超过23:00分）
     * @param clockTime
     * @return
     */
    public static int calculateIsSubsidy(ClockTime clockTime){
        if (StringUtils.isEmpty(clockTime.getSixthTime())){
            return 0;
        }
        int hour = getHourOrMinute(clockTime.getSixthTime(), true);
        if (hour >= 23){
            return 1;
        }
        return 0;
    }

    /**
     * 计算正常上班工时
     * @param clockTime
     * @return
     */
    public static float calculateNormalHours(ClockTime clockTime){
        //正常工时：上午：8:00-11:40 算3.5个小时，超过220分钟；下午：13:10-17:30，算4.5个小时，260分钟
        float morningTime = Float.valueOf(callTime(clockTime.getSecondTime(), clockTime.getFirstTime()));
        float afternoonTime = Float.valueOf(callTime(clockTime.getFourthTime(), clockTime.getThirdTime()));
        float normalHours = 0f;
        if (morningTime >= 190f){//上班迟到半小时之内的，算迟到，工时还是3.5个小时
            normalHours += 3.5f;
        }else{
            //如170f/60f，得到2.83，工时应该取2.5
            float getFloatHours = morningTime/60f;
            int getIntHour = (int)getFloatHours;
            if (getFloatHours >= (getIntHour + 0.5)){
                normalHours += (getIntHour + 0.5);
            }else{
                normalHours += getIntHour;
            }
        }

        if(afternoonTime >= 230f){//迟到半个小时之内的话，算迟到，工时还是4.5个小时
            normalHours += 4.5f;
        }else{
            //如170f/60f，得到2.83，工时应该取2.5
            float getFloatHours = morningTime/60f;
            int getIntHour = (int)getFloatHours;
            if (getFloatHours >= (getIntHour + 0.5)){
                normalHours += (getIntHour + 0.5);
            }else{
                normalHours += getIntHour;
            }
        }
        return normalHours;
    }

    /**
     * 计算加班工时
     * @param endTime
     * @return
     */
    public static float calculateExtraHours(String endTime, String startTime){
        //两个有值的情况下才计算的
        float extraHours = 0f;
        if (StringUtils.isEmpty(endTime) && StringUtils.isEmpty(startTime)){
            return extraHours;
        }
        //加班从18:30
//        float extraTime = Float.valueOf(callTime(clockTime.getSixthTime(), clockTime.getFifthTime()));
        float extraTime = (float) callTime(endTime, startTime);
        float getFloatHours = extraTime/60f;
        int getIntHour = (int)getFloatHours;
        if (getFloatHours >= (getIntHour + 0.5)){
            extraHours += (getIntHour + 0.5);
        }else{
            extraHours += getIntHour;
        }
        return extraHours;
    }

    /**
     * 计算迟到分钟数
     * @param clockTime
     * @return
     */
    public static int calculateLateMinutes(ClockTime clockTime){
        int lateTime = 0;
        //算出第一个卡 time1为正则加为负则正常
        int time1 = 0;
        int time2 = 0;
        int time3 = 0;
        int time4 = 0;
        if(!StringUtils.isEmpty(clockTime.getFirstTime())){
            time1 = callTime(clockTime.getFirstTime(), "08:00");
        }
        if(!StringUtils.isEmpty(clockTime.getSecondTime())){
            time2 = callTime("11:40", clockTime.getSecondTime());
        }
        if(!StringUtils.isEmpty(clockTime.getThirdTime())){
            time3 = callTime(clockTime.getThirdTime(), "13:10");
        }
        if(!StringUtils.isEmpty(clockTime.getFourthTime())){
            time4 = callTime("17:30", clockTime.getFourthTime());
        }
        if (time1 > 0){
            lateTime+=time1;
        }else if (time2 > 0){
            lateTime+=time2;
        }else if (time3 > 0){
            lateTime+=time3;
        }else if (time4 > 0){
            lateTime+=time4;
        }
        return lateTime;
    }


    /**
     * 整理好六个打卡时间
     * @param time
     * @return
     */
    public static ClockTime sortClockTime(String time, boolean isWeekend){
        //转化时间
        String[] splitTime = time.split(" ");
        int timeLength = splitTime.length;
        //长度少于3个卡直接返回空并且不是周末的时候
//        if (timeLength < 4 && !isWeekend){
//            return null;
//        }
        List<String> list1 = new ArrayList<>();
        List<String> list2 = new ArrayList<>();
        List<String> list3 = new ArrayList<>();
        List<String> list4 = new ArrayList<>();
        for (int i=0; i<timeLength; i++){
            int hourOrMinute = getHourOrMinute(splitTime[i], true);
            //第一个打卡 早上0-11点的归一类（有凌晨打卡的）
            if (hourOrMinute>=0 && hourOrMinute<11){
                list1.add(splitTime[i]);
            }else if(hourOrMinute>=11 && hourOrMinute<16 && !list2.contains(splitTime[i])){
                //第二个、第三个打卡，中午11-16点的归一类
                list2.add(splitTime[i]);
            }else if(hourOrMinute>=16 && hourOrMinute<19 && !list3.contains(splitTime[i])){
                //第四个、第五个打卡，下午16-19点的归一类
                list3.add(splitTime[i]);
            }else if(hourOrMinute>=19 && hourOrMinute <=24){
                //第六个打卡，下午19-24点的归一类
                list4.add(splitTime[i]);
            }
        }
        //如果前面三个卡没有的话,并且不是周末的话，就返回null
//        if ((list1.size() == 0  || list2.size() < 2) && !isWeekend){
//            return null;
//        }
        //把四个list转换成ClockTime
        ClockTime clockTime = listToClockTime(list1, list2, list3, list4, isWeekend);
        return clockTime;
    }

    /**
     * 把list转化为ClockTime实体
     * @param list1 第一个卡 0-11点
     * @param list2 第二、三个卡 11-16 点
     * @param list3 第四、五个卡 16-19点
     * @param list4 第六个卡 19：00-24:00
     * @return
     */
    private static ClockTime listToClockTime(List<String> list1, List<String> list2, List<String> list3, List<String> list4, boolean isWeekend){
        //不满足打卡的个数，直接返回空值；规则：周一-周五必须上满8个小时，周六周天不强制
//        if ((list1.size() == 0 || list2.size() < 2) && !isWeekend){
//            return null;
//        }
        ClockTime clockTime = new ClockTime();
        //list1
        if (list1.size()>0 &&StringUtils.isNotEmpty(list1.get(0))){
            clockTime.setFirstTime(list1.get(0));
        }
        //list2
        if (list2.size()>0 && StringUtils.isNotEmpty(list2.get(0))){
            clockTime.setSecondTime(list2.get(0));//取第一个值
        }
        if (list2.size()>0 && list2.size()>=2){
            clockTime.setThirdTime(list2.get(list2.size()-1));//取最后一个值
        }
        //list3
        if (list3.size() == 1 || (list3.size() > 1 && callTime(list3.get(list3.size()-1), list3.get(0))<=3)){//list只有一个值或者第一个和最后一个值相差不超过3分钟
            //list3只有一个的情况下，>=17:30 && < 18:00算第四个卡，>=18:00算第五个卡
            if (callTime(list3.get(0), "17:30")>=0 && callTime( "18:00", list3.get(0))>0){
                clockTime.setFourthTime(list3.get(0));
            }else{
                clockTime.setFifthTime(list3.get(0));
            }
        }else if (list3.size() > 1 && callTime(list3.get(list3.size()-1), list3.get(0))>3){//超过两个卡的话,第一个和最后一个值相差超过3分钟
            clockTime.setFourthTime(list3.get(0));
            clockTime.setFifthTime(list3.get(list3.size()-1));
        }
        //list4
        if(list4.size() != 0){
            clockTime.setSixthTime(list4.get(0));
        }
        LOGGER.info("listToClockTime,clockTime:{}",  JSON.toJSON(clockTime));
        return clockTime;
    }
}